package com.jichaoyun.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

import com.jichaoyun.common.enums.MyExceptiontType;
import com.jichaoyun.common.ex.MyException;
import com.jichaoyun.common.model.PagedResult;
import com.jichaoyun.dao.mapper.BalanceAlarmMapper;
import com.jichaoyun.dao.mapper.LineInfoMapper;
import com.jichaoyun.dao.mapper.StationInfoMapper;
import com.jichaoyun.dao.mapper.UserMapper;
import com.jichaoyun.model.entity.BalanceAlarm;
import com.jichaoyun.model.entity.LineInfo;
import com.jichaoyun.model.entity.StationInfo;
import com.jichaoyun.model.entity.User;
import com.jichaoyun.service.IBalanceAlarmService;
import com.jichaoyun.service.IStationInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;

/**
* @author zhen
* @description 针对表【balanceAlarm】的数据库操作Service实现
* @createDate 2023-12-08 11:11:54
*/
@Service
public class BalanceAlarmServiceImpl extends ServiceImpl<BalanceAlarmMapper, BalanceAlarm>
    implements IBalanceAlarmService {

    @Autowired
    private UserMapper userMapper;

    @Resource
    private BalanceAlarmMapper balancealarmMapper;

    @Resource
    private StationInfoMapper stationInfoMapper;

    @Resource
    private LineInfoMapper lineInfoMapper;

    @Resource
    private IStationInfoService stationInfoService;

    /**
     * 余额报警信息已读接口
     * @param userId
     */
    @Override
    public void MakeAlarmRead(Integer id,Integer userId) {
        LambdaQueryWrapper<User> queryWrapper0 = new LambdaQueryWrapper<>();
        queryWrapper0.eq(User::getId,userId);
        User user = this.userMapper.selectOne(queryWrapper0);

        if(user.getUserRole() != 0){
            LambdaQueryWrapper<BalanceAlarm> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(BalanceAlarm::getId,id);
            BalanceAlarm balanceAlarm = this.balancealarmMapper.selectOne(wrapper);
            balanceAlarm.setIsReadAdmin(true);
            this.balancealarmMapper.updateById(balanceAlarm);
        }else {
            LambdaQueryWrapper<BalanceAlarm> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(BalanceAlarm::getId,id);
            BalanceAlarm balanceAlarm = this.balancealarmMapper.selectOne(wrapper);
            balanceAlarm.setIsRead(true);
            this.balancealarmMapper.updateById(balanceAlarm);
        }

    }
    /**
     * 全部余额报警信息已读接口
     * @param userId
     */
    @Override
    public void MakeAlarmRead(Integer userId) {

        LambdaQueryWrapper<User> queryWrapper0 = new LambdaQueryWrapper<>();
        queryWrapper0.eq(User::getId,userId);
        User user = this.userMapper.selectOne(queryWrapper0);

        if(user.getUserRole() != 0){
            LambdaQueryWrapper<BalanceAlarm> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(BalanceAlarm::getIsReadAdmin,0);
            List<BalanceAlarm> BalanceAlarmList = this.balancealarmMapper.selectList(lambdaQueryWrapper);

            for(BalanceAlarm balanceAlarm:BalanceAlarmList){
                balanceAlarm.setIsReadAdmin(true);
                this.balancealarmMapper.updateById(balanceAlarm);
            }

        }else {
            LambdaQueryWrapper<StationInfo> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(StationInfo::getUserId,userId);
            List<StationInfo> stationInfoList = this.stationInfoMapper.selectList(queryWrapper);

            List<Integer> stationNoList = new ArrayList<>();
            for(StationInfo stationInfo:stationInfoList){
                stationNoList.add(stationInfo.getStationNo());
            }
            if(stationNoList.isEmpty()){
                throw new MyException(MyExceptiontType.Other,null);
            }

            LambdaQueryWrapper<BalanceAlarm> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.in(BalanceAlarm::getStationNo,stationNoList)
                              .eq(BalanceAlarm::getIsRead,0);
            List<BalanceAlarm> BalanceAlarmList = this.balancealarmMapper.selectList(lambdaQueryWrapper);

            for(BalanceAlarm balanceAlarm:BalanceAlarmList){
                balanceAlarm.setIsRead(true);
                this.balancealarmMapper.updateById(balanceAlarm);
            }
        }
    }
    /**
     * 查询未读的余额报警信息
     * @return
     */
    @Override
    public List<Map<String,Object>> pollingDb(Integer userId) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getId,userId);
        User user = this.userMapper.selectOne(queryWrapper);
        if(user.getUserRole() != 0) {
            //查询所有管理员未读的报警
            LambdaQueryWrapper<BalanceAlarm> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(BalanceAlarm::getIsReadAdmin, 0).orderByDesc(BalanceAlarm::getId);
            List<BalanceAlarm> list0 = balancealarmMapper.selectList(wrapper);
            // 创建一个 Map 来存储每个 station_name 的最新记录
            Map<String, BalanceAlarm> latestAlarms = new HashMap<>();
            List<BalanceAlarm> list =new ArrayList<>();
            // 遍历查询结果，保留每个 station_name 的最新记录
            for (BalanceAlarm alarm : list0) {
                String stationName = alarm.getStationName();
                if (!latestAlarms.containsKey(stationName)) {
                    latestAlarms.put(stationName, alarm);
                    list.add(alarm);
                }
            }
            if (list != null) {
                List<Map<String, Object>> resList = new ArrayList<>();
                for(BalanceAlarm item : list){
                    Map<String, Object> map = new HashMap<>();
                    map.put("报警类型","余额报警");
                    map.put("id",item.getId());
                    map.put("报警站点",item.getStationName());
                    map.put("报警时间",item.getTime().toString());
                    resList.add(map);
                }
                return resList;
            }
        }
        else {
            LambdaQueryWrapper<StationInfo> queryWrapper1 = new LambdaQueryWrapper<>();
            queryWrapper1.eq(StationInfo::getUserId,userId);
            List<StationInfo> stationInfoList = this.stationInfoMapper.selectList(queryWrapper1);

            List<Integer> stationNoList = new ArrayList<>();
            for(StationInfo stationInfo:stationInfoList){
                stationNoList.add(stationInfo.getStationNo());
            }

            //查询单个用户所有站点未读的报警
            LambdaQueryWrapper<BalanceAlarm> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(BalanceAlarm::getIsRead,0)
                    .in(BalanceAlarm::getStationNo,stationNoList)
                    .orderByDesc(BalanceAlarm::getId);
            List<BalanceAlarm> list0 = balancealarmMapper.selectList(wrapper);
            // 创建一个 Map 来存储每个 station_name 的最新记录
            Map<String, BalanceAlarm> latestAlarms = new HashMap<>();
            List<BalanceAlarm> list =new ArrayList<>();
            // 遍历查询结果，保留每个 station_name 的最新记录
            for (BalanceAlarm alarm : list0) {
                String stationName = alarm.getStationName();
                if (!latestAlarms.containsKey(stationName)) {
                    latestAlarms.put(stationName, alarm);
                    list.add(alarm);
                }
            }

            if(list != null){
                List<Map<String,Object>> resList = new ArrayList<>();
                for(BalanceAlarm item : list){
                    Map<String, Object> map = new HashMap<>();
                    map.put("报警类型","余额报警");
                    map.put("id",item.getId());
                    map.put("报警站点",item.getStationName());
                    map.put("报警时间",item.getTime().toString());
                    resList.add(map);
                }

                return resList;
            }
        }
        return null;
    }

    /**
     * 余额报警用户占比分析
     * @return
     */
    @Override
    public Map<String, Object> selectBalanceAlarmCountALL() {
        List<BalanceAlarm> balanceAlarmList = balancealarmMapper.selectList(null);

        LinkedHashMap<String, Object> resMap = new LinkedHashMap<>();

        getAccountByBalanceAlarmList(balanceAlarmList, resMap);

        return resMap;
    }

    private void getAccountByBalanceAlarmList(List<BalanceAlarm> balanceAlarmList, LinkedHashMap<String, Object> resMap) {
        //初始化所有的线路为0
        List<LineInfo> lineInfos = lineInfoMapper.selectList(null);
        for (LineInfo lineInfo : lineInfos) {
            String line_name =  lineInfo.getLineAlias();
            if(line_name==null ||line_name.equals("")){
                line_name = lineInfo.getLineName();
            }
            resMap.put(line_name,0);
        }

        //给每个路线的余额报警进行累计
        for (BalanceAlarm balancealarm : balanceAlarmList) {
            Integer station_no = balancealarm.getStationNo();
            String line_name =  lineInfoMapper.selectById(stationInfoMapper.selectById(station_no).getLineId()).getLineAlias();
            if(line_name==null ||line_name.equals("")){
                line_name = lineInfoMapper.selectById(stationInfoMapper.selectById(station_no).getLineId()).getLineName();
            }
            Integer old =(Integer) resMap.get(line_name);
            resMap.put(line_name,old+1);
        }

        //去掉值为0的resMap里面的键值对
        Iterator<Map.Entry<String, Object>> iterator = resMap.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, Object> entry = iterator.next();
            if ((Integer)entry.getValue() == 0) {
                iterator.remove();
            }
        }

        // 将resMap里面的每个值转化成其在所有余额报警中的占比，占比用百分比表示，百分比保留1位小数
        for (Map.Entry<String, Object> entry : resMap.entrySet()) {
            Integer value = (Integer) entry.getValue();
            Integer all = balanceAlarmList.size();
            resMap.put(entry.getKey(),String.format("%.1f",value*100f/all) + '%');
        }
    }

    /**
     * 某年某月余额报警用户占比分析
     * @return
     */
    @Override
    public Map<String, Object> selectBalanceAlarmCountByMonth(LocalDateTime start, LocalDateTime end) {
        if(start!=null && end!=null){
            LambdaQueryWrapper<BalanceAlarm> wrapper = new LambdaQueryWrapper<>();
            wrapper.between(BalanceAlarm::getTime,start,end);
            List<BalanceAlarm> balanceAlarmList = balancealarmMapper.selectList(wrapper);

            LinkedHashMap<String, Object> resMap = new LinkedHashMap<>();

            getAccountByBalanceAlarmList(balanceAlarmList, resMap);

            return resMap;
        }else{
            return null;
        }
    }

    /**
     * 某年某月余额报警趋势
     * @param start
     * @param end
     * @return
     */
    @Override
    public Map<String, Object> selectBalanceAlarmListByMonth(LocalDateTime start, LocalDateTime end) {
        if(start!=null && end!=null){
            HashMap<String, Object> hashMap = new LinkedHashMap<>();
            QueryWrapper<BalanceAlarm> wrapper = new QueryWrapper<>();
            wrapper.between("time",start,end).orderByAsc("time");
            List<BalanceAlarm> balanceAlarmList = balancealarmMapper.selectList(wrapper);

            for (int i =0;i<start.toLocalDate().lengthOfMonth();i++){
                hashMap.put(i+1+"日",0);
            }

            for (BalanceAlarm balancealarm  : balanceAlarmList) {
                String day = balancealarm.getTime().getDayOfMonth() + "日";
                Integer old = (Integer) hashMap.get(day);
                hashMap.put(day, old+1);
            }
            return hashMap;
        }else{
            return null;
        }
    }

    /**
     * 某年某月某条路线余额报警趋势
     * @param start
     * @param end
     * @return
     */
    @Override
    public Map<String, Object> selectBalanceAlarmListByMonthAndLine(Integer lineId, LocalDateTime start, LocalDateTime end) {
        if(start!=null && end!=null){
            HashMap<String, Object> hashMap = new LinkedHashMap<>();
            QueryWrapper<BalanceAlarm> wrapper = new QueryWrapper<>();
            wrapper.between("time",start,end).orderByAsc("time");
            List<BalanceAlarm> balanceAlarmList = balancealarmMapper.selectList(wrapper);

            for (int i =0;i<start.toLocalDate().lengthOfMonth();i++){
                hashMap.put(i+1+"日",0);
            }

            for (BalanceAlarm balancealarm  : balanceAlarmList) {
                Integer lineId1 = lineInfoMapper.selectById(stationInfoMapper.selectById(balancealarm.getStationNo()).getLineId()).getLineNum();
                if (lineId1.equals(lineId)){
                    String day = balancealarm.getTime().getDayOfMonth() + "日";
                    Integer old = (Integer) hashMap.get(day);
                    hashMap.put(day, old+1);
                }
            }
            return hashMap;
        }else{
            return null;
        }
    }

    /**
     * 余额报警信息查询
     * @param pageNo
     * @return
     */
    @Override
    public PagedResult selectAllBalanceAlarmListByPage(Integer pageNo) {
        PagedResult pagedResult = new PagedResult();
        Page<BalanceAlarm> objectPage = new Page<>(pageNo,10);
        QueryWrapper<BalanceAlarm> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc("time");
        Page<BalanceAlarm> balancealarmPage = balancealarmMapper.selectPage(objectPage, wrapper);
        pagedResult.setPages(balancealarmPage.getPages());
        pagedResult.setTotal(balancealarmPage.getTotal());

        HashMap<String, Object> listMap = new HashMap<>();
        List<HashMap<String, Object> > resMaplist = new ArrayList<>();
        List<BalanceAlarm> balanceAlarmList = balancealarmPage.getRecords();
        for (BalanceAlarm balancealarm : balanceAlarmList) {
            listMap.put("站号",balancealarm.getStationNo());
            listMap.put("用户名",balancealarm.getStationName());
            listMap.put("时间",balancealarm.getTime());
            listMap.put("余额",balancealarm.getBalance());
            listMap.put("余额预警值",balancealarm.getBalanceAlarm());
            listMap.put("最大透支量",balancealarm.getMaxOverdraft());
            resMaplist.add(listMap);
        }
        pagedResult.setRows(resMaplist);


        return pagedResult;
    }

    /**
     * 某条线路余额报警信息查询
     * @param pageNo
     * @return
     */
    @Override
    public PagedResult selectAllBalanceAlarmListByPageAndLine(Integer lineId, Integer pageNo) {
        PagedResult pagedResult = new PagedResult();

        PageHelper.startPage(pageNo,10);
        List<BalanceAlarm> balanceAlarmList = balancealarmMapper.selectByPageAndLineId(lineId);

        PageInfo<BalanceAlarm> objectPageInfo = new PageInfo<>(balanceAlarmList);

        pagedResult.setPages(objectPageInfo.getPages());
        pagedResult.setTotal(objectPageInfo.getTotal());



        List<HashMap<String, Object> > resMaplist = new ArrayList<>();
        List<BalanceAlarm> balanceAlarmPageList = objectPageInfo.getList();


        for (BalanceAlarm balancealarm : balanceAlarmPageList) {
            HashMap<String, Object> listMap = new HashMap<>();
            listMap.put("站号",balancealarm.getStationNo());
            listMap.put("用户名",balancealarm.getStationName());
            listMap.put("时间",balancealarm.getTime());
            listMap.put("余额",balancealarm.getBalance());
            listMap.put("余额预警值",balancealarm.getBalanceAlarm());
            listMap.put("最大透支量",balancealarm.getMaxOverdraft());
            resMaplist.add(listMap);
        }
        pagedResult.setRows(resMaplist);

        return pagedResult;
    }

}




